//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.3.1
/********************************************************
    说明：
    1、基于W25Qxx的驱动。
    2、当前只硬件SPI。
	3、基于FreeRTOS,基于spi_bus.h。
    4、本驱动提供一个可修改大小的收发缓存。
	5、基于硬件spi读写时会自动更具数据长度选择DMA模式和普通模式。
	6、基于FreeRTOS,自动让出CPU资源，并能及时响应读写完成。
	7、片选NSS依据spi_bus.c里面的配置自动初始化软NSS。
	8、提供flash操作状态。
**********************************************************/
#ifndef __FLASH_DRIVER_H__
#define __FLASH_DRIVER_H__

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "../../BSP/SPI_BSP/spi_bus.h"
#include "../../BSP/GPIO_BSP/gpio_bsp.h"


#define FLASH_BUFF_SIZE         flash_sector_size_byte


//SPI NSS
#define FLASH_NSS_GPIO_PORT     PortC
#define FLASH_NSS_GPIO_PIN     	Pin0

typedef enum
{
	Jedec_Device_ID_W25X16  = 0xEF3015,
	Jedec_Device_ID_W25Q08  = 0xEF4014,
	Jedec_Device_ID_W25Q16  = 0xEF4015,
	Jedec_Device_ID_W25Q32  = 0xEF4016,
	Jedec_Device_ID_W25Q64  = 0XEF4017,
	Jedec_Device_ID_W25Q128 = 0XEF4018,
	Jedec_Device_ID_W25Q256 = 0XEF4019,
}WHT_Flash_ID_enum;

typedef enum//W25Q128
{
	flash_sector_size_byte = 4096,	//1扇区字节
	flash_sector_size      = 16,	//扇区个数
	flash_block_size_byte  = 65536,	//1块字节
	flash_block_size       = 256,	//块个数
	flash_page_size_byte   = 256,	//页缓存区字节
	flash_page_size        = 65536,	//总共页数
	flash_size_byte        = 16777216,//flash总字节
	flash_addr_size        = 16777216,//flash总地址
}WHT_Flash_Size_enum;

typedef enum//毫秒
{
	Write_Status_Register_Time = 15,   //写入状态寄存器  平均15ms
	Page_Program_Time          = 3,    //页写入          平均0.7ms
	Sector_Erase_Time_4KB      = 400,  //扇区擦除        平均30ms
	Block_Erase_Time_32KB      = 800,  //半块擦除        平均120ms
	Block_Erase_Time_64KB      = 1000, //块擦除          平均150ms
	Chip_Erase_Time            = 30000,//芯片擦除        平均15000ms
}WHT_W25Q_Erase_Time_enum;

typedef enum
{
	Sector_Erase_4KB = 0,
	Block_Erase_32KB = 1,
	Block_Erase_64KB = 2,
	Chip_Erase_All   = 3,
}WHT_W25Q_Erase_Sel_enum;

typedef enum//FLASH 常用命令
{
	W25Q_Write_Enable       = 0x06,//写使能
	W25Q_Write_Disable      = 0x04,//写禁用
	W25Q_Read_Status_Reg    = 0x05,//读取状态寄存器1
	W25Q_Write_Status_Reg   = 0x01,//写入状态寄存器
	W25Q_Read_Data          = 0x03,//读取数据
	W25Q_Fast_Read_Data     = 0x0B,//快速读取数据
	W25Q_Fast_Read_Dual     = 0x3B,//快速读取双IO输出
	W25Q_Page_Program       = 0x02,//页面写入最多256字节
	W25Q_Block_Erase_32     = 0x52,//块擦除32KB
	W25Q_Block_Erase_64     = 0xD8,//块擦除64KB
	W25Q_Sector_Erase       = 0x20,//扇区擦除
	W25Q_Chip_Erase         = 0xC7,//芯片擦除
	W25Q_Power_Down         = 0xB9,//断电
	W25Q_Release_Power_Down = 0xAB,//释放断电
	W25Q_Device_ID          = 0xAB,//设备ID
	W25Q_Manufact_Device_ID = 0x90,//制造商设备ID
	W25Q_Jedec_Device_ID    = 0x9F,//Jedec设备ID
}WHT_W25Q_Instruction_enum;

typedef enum//扇区相差4096个字节即4K字节
{
	sector0  = 0x00000000,
	sector1  = 0x00001000,
	sector2  = 0x00002000,
	sector3  = 0x00003000,
	sector4  = 0x00004000,
	sector5  = 0x00005000,
	sector6  = 0x00006000,
	sector7  = 0x00007000,
	sector8  = 0x00008000,
	sector9  = 0x00009000,
	sector10 = 0x0000A000,
	sector11 = 0x0000B000,
	sector12 = 0x0000C000,
	sector13 = 0x0000D000,
	sector14 = 0x0000E000,
	sector15 = 0x0000F000,
}WHT_Sector_enum;

typedef enum
{
    Flash_TRx_Idle = 0,//空闲
    Flash_TRx_Busy = 1,//忙碌

    Flash_No_Error = 0,//无错误码
	Flash_Error    = 1,//通信错误
}WHT_Flash_State_enum;

typedef struct
{
	WHT_Flash_State_enum Idle_State; //flash状态,自动清除
	WHT_Flash_State_enum Error_State;//flash错误状态,自动清除
}WHT_Flash_State_t;


typedef struct
{
	volatile WHT_Flash_State_t* WHT_Flash_State;//Flash的状态
	uint8_t* WHT_TRx_Buffer;                    //收发缓存，大小为FLASH_BUFF_SIZE
	void (*WHT_Init)(void);                     //初始化
	uint32_t (*WHT_Read_JEDEC_ID)(void);        //读取Flash Dedec ID
	void (*WHT_Erase)(WHT_W25Q_Erase_Sel_enum erase_sel, uint32_t block_number, WHT_Sector_enum sector_number);//选择擦除
	void (*WHT_Read_Data)(uint32_t read_addr, uint32_t count);   //随机地址读取,最大 FLASH_BUFF_SIZE
	void (*WHT_Write_Data)(uint32_t write_addr, uint32_t count); //随机地址写入,最大 FLASH_BUFF_SIZE
	void (*WHT_Write_Page)(uint32_t page_number, uint32_t count);//随机页写入,最大 flash_page_size_byte
#if (FLASH_BUFF_SIZE >= flash_sector_size_byte)
	void (*WHT_Write_Sector)(uint32_t block_number, WHT_Sector_enum sector_number);//随机扇区扇区写入,写入 flash_sector_size_byte
#endif
}WHT_Flash_Driver_t;

extern const WHT_Flash_Driver_t WHT_Flash_Driver;

#endif /*__FLASH_DRIVER_H__*/
